Skip to content

Conversation

@jfreden
Copy link
Contributor

@jfreden jfreden commented Mar 11, 2025

This PR overloads the process method and allows it to be used with several ReservedStateChunks. The purpose is to allow several state chunks to be spread across several files but handled as a single cluster state update by validating and merging them into a single representation of the ReservedStateChunk.

@elasticsearchmachine elasticsearchmachine added the serverless-linked Added by automation, don't add manually label Mar 11, 2025
@jfreden jfreden changed the title Support reserved state to be spread accross several files Support reserved state to be spread across several files Mar 11, 2025
@jfreden jfreden force-pushed the change_mp_file_processing branch from 2d34177 to 4095a58 Compare March 12, 2025 12:24
@jfreden jfreden changed the title Support reserved state to be spread across several files Allow passing several reserved state chunks in single process call Mar 12, 2025
}

ReservedStateChunk parse(ProjectId projectId, String namespace, XContentParser parser) {
public ReservedStateChunk parse(ProjectId projectId, String namespace, XContentParser parser) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be used by a caller to parse several state chunks before passing them to process.

return;
}

if (errorState.projectId().isPresent() && clusterService.state().metadata().hasProject(errorState.projectId().get()) == false) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug. If parsing fails for a project that doesn't exist yet, the error state reporting won't work since it's persisted in the project metadata that doesn't exist yet. This case needs to be handled in the caller (multi-project file service).

@jfreden jfreden added the :Core/Infra/Settings Settings infrastructure and APIs label Mar 12, 2025
@jfreden jfreden requested a review from prdoyle March 12, 2025 12:35
@jfreden jfreden marked this pull request as ready for review March 12, 2025 12:35
@elasticsearchmachine elasticsearchmachine added the Team:Core/Infra Meta label for core/infra team label Mar 12, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@elasticsearchmachine
Copy link
Collaborator

Hi @jfreden, I've created a changelog YAML for you.

);
}

private static ReservedStateChunk mergeReservedStateChunks(List<ReservedStateChunk> chunks) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are merging the list of chunks into a single ReservedStateChunk, why do we also need to change the process method signature? Maybe I am missing something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do want to change the process method signature, I'd think it is probably more useful to accept a Map<String, ReservedStateChunk> so that each chunk can be stored in its own namespace rather than a single one. This seems useful to separate regular settings and secrets. It does lead to more code changes. So maybe that is something you are trying to avoid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out! I've spent some time thinking about this.

Since we are merging the list of chunks into a single ReservedStateChunk, why do we also need to change the process method signature? Maybe I am missing something?

Before this change process was called with an XContentParser instance (the parser for the json files), once for each file. This is still supported.

With this change we call process once per project to trigger a single cluster state update instead of two and that's why we need to either call process with one parser for each file (I find this approach a little awkward) or call the parse method from the caller MultiProjectFileSettingsService and then pass the resulting ReservedStateChunk instances to process (this is the approach I went with).

If we do want to change the process method signature, I'd think it is probably more useful to accept a Map<String, ReservedStateChunk> so that each chunk can be stored in its own namespace rather than a single one. This seems useful to separate regular settings and secrets. It does lead to more code changes. So maybe that is something you are trying to avoid?

The purpose of this change is to be able to spread the state for a single namespace across several chunks. Since reserved state is versioned per namespace I think it makes the most sense to have a single one for both.

The alternative I think you're proposing is to have several reserved state namespaces in a single cluster state update. We'd then have to add version dependencies between namespaces, which I think is out of scope for the ReservedClusterStateService but could definitely be implemented in the MultiProjectFileSettingsService. I'm leaning towards sticking with a single namespace, but happy to discuss this further.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this change process was called with an XContentParser instance

Thanks for explaining. I see the issue now.

The alternative I think you're proposing is to have several reserved state namespaces in a single cluster state update.

After commenting on the other PR about passing down both project settings and secrets at the same time, I now think it might be better to use a single namespace as you have proposed. Sorry for the back and forth.

Copy link
Contributor

@prdoyle prdoyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense. I'm struggling a little with the biger picture. Does the control plane logic need to exercise special care to make sure all the files arrive "at the same time"? What happens if there's some lag between when some files arrive versus others, and the processing happens inbetween?

try {
reservedStateChunk = reservedStateChunks.size() == 1
? reservedStateChunks.getFirst()
: mergeReservedStateChunks(reservedStateChunks);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Seems to me mergeReservedStateChunks could handle this case for you. Then the caller doesn't need a ternary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's nicer! Thanks!

@jfreden
Copy link
Contributor Author

jfreden commented Mar 19, 2025

I think it makes sense. I'm struggling a little with the biger picture. Does the control plane logic need to exercise special care to make sure all the files arrive "at the same time"? What happens if there's some lag between when some files arrive versus others, and the processing happens inbetween?

If one file comes in before the other, the processing will fail and be retried when all files are there. We will try to apply reserved state for every file change.

@jfreden jfreden added the auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label Mar 19, 2025
@elasticsearchmachine elasticsearchmachine merged commit fc7fbdf into elastic:main Mar 20, 2025
17 checks passed
@jfreden jfreden deleted the change_mp_file_processing branch March 20, 2025 08:31
afoucret pushed a commit to afoucret/elasticsearch that referenced this pull request Mar 21, 2025
…lastic#124574)

This PR overloads the `process` method and allows it to be used with
several `ReservedStateChunks`. The purpose is to allow several state
chunks to be spread across several files but handled as a single cluster
state update by validating and merging them into a single representation
of the `ReservedStateChunk`.
smalyshev pushed a commit to smalyshev/elasticsearch that referenced this pull request Mar 21, 2025
…lastic#124574)

This PR overloads the `process` method and allows it to be used with
several `ReservedStateChunks`. The purpose is to allow several state
chunks to be spread across several files but handled as a single cluster
state update by validating and merging them into a single representation
of the `ReservedStateChunk`.
omricohenn pushed a commit to omricohenn/elasticsearch that referenced this pull request Mar 28, 2025
…lastic#124574)

This PR overloads the `process` method and allows it to be used with
several `ReservedStateChunks`. The purpose is to allow several state
chunks to be spread across several files but handled as a single cluster
state update by validating and merging them into a single representation
of the `ReservedStateChunk`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) :Core/Infra/Settings Settings infrastructure and APIs >enhancement serverless-linked Added by automation, don't add manually Team:Core/Infra Meta label for core/infra team v9.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants